package mygang.service;

import mygang.service.manager.RoleService;
import java.util.List;
import mygang.dao.UserDAO;
import mygang.helper.Consts;
import mygang.model.Role;
import mygang.model.User;
import mygang.model.UserWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.dao.ReflectionSaltSource;
import org.springframework.security.authentication.encoding.ShaPasswordEncoder;
import org.springframework.stereotype.Service;

/**
 *
 * @author Volodymyr Lavrynovych <volodya.lavrynovych@gmail.com>
 */
@Service("userService")
public class UserServiceImpl<D extends UserDAO> extends AbstractService<D> implements UserService {

    @Autowired
    private ReflectionSaltSource saltSource;
    @Autowired
    private RoleService roleService;
    private ShaPasswordEncoder sha = new ShaPasswordEncoder(512);

    @Override
    public List<User> getAll() {
        return getDao().getAll();
    }

    public void add(User user) throws Exception {
        user.setPassword(sha.encodePassword(user.getPassword(), saltSource.getSalt(new UserWrapper(user))));
        
        // check role and add default if it need
        if(user.getRoles().isEmpty()) {
            Role defaultRole = roleService.findByName(Consts.ROLE_USER);
            if(defaultRole!=null) {
                user.getRoles().add(defaultRole);
            }
        }
        
        try {
            save(user);
        } catch (Exception ex) {
            String message = "";
            Throwable throwable = ex;
            do {
                if (throwable.getMessage().indexOf("UK_USER_LOGIN") != -1) {
                    message = "User with the same name already exists";
                    log.error(message + "\n" + ex);
                }
            } while ((throwable = throwable.getCause()) != null);
            throw new Exception(message, ex);
        }
    }
    
    public void update(User user) throws Exception {
        user.setPassword(sha.encodePassword(user.getPassword(), saltSource.getSalt(new UserWrapper(user))));
        if(user.getRoles().isEmpty()) {
            user.getRoles().add(roleService.findByName("ROLE_ADMIN"));
        }
        try {
            save(user);
        } catch (Exception ex) {
            log.debug("---------------------update--"+ex.getMessage());
            String message = "";
            Throwable throwable = ex;
            do {
                if (throwable.getMessage().indexOf("UK_USER_LOGIN") != -1) {
                    message = "User with the same name already exists";
                    log.error(message + "\n" + ex);
                }
            } while ((throwable = throwable.getCause()) != null);
            throw new Exception(message, ex);
        }
    }
    
    public void delete(long id) {
        getDao().delete(id);
    }

    public User findByLogin(String login) {
        return getDao().findByLogin(login);
    }

    public void save(User obj) {
        getDao().save(obj);
    }

    public User getById(long id) {
        throw new UnsupportedOperationException("Not supported yet.");
    }
}
